<?php

namespace app\common\model;

use app\common\library\MemberVo;
use app\common\traits\TimeToStringTrait;
use EasyWeChat\MiniProgram\Auth\Client;
use think\Model;

/**
 * 模型
 */
class Order extends Model
{
    use TimeToStringTrait;

    // 表名
    protected $name = 'order';
    protected $deleteTime = false;
    // 开启自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';
    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';

    // 追加属性
    protected $append = [

    ];
    const ORDER_STATUS_CANCEL       = 0; // 取消
    const ORDER_STATUS_WAIT_PAY     = 1; // 待支付
    const ORDER_STATUS_WAIT_AUDIT   = 2; // 待核销
    const ORDER_STATUS_WAIT_COMMENT = 3; // 待评价
    const ORDER_STATUS_OK           = 4; // 已完成
    const ORDER_STATUS_REFUND       = 5; // 退款/售后

    const PAY_STATUS_NO               = 0; // 未支付
    const PAY_TYPE_WECHAT             = 1; // 微信
    const PAY_TYPE_BALANCE            = 2; // 余额
    const PAY_TYPE_WECHAT_AND_BALANCE = 3; // 余额 + 微信

//    const REFUND_STATUS_APPLY   = 1;   // 审核申请
//    const REFUND_STATUS_SUCCESS = 2;   // 审核通过
//    const REFUND_STATUS_FAIL    = 3;   // 审核拒绝
//
//    static $refundMap = [
//        self::REFUND_STATUS_APPLY   => '退款申请中',
//        self::REFUND_STATUS_SUCCESS => '退款成功',
//        self::REFUND_STATUS_FAIL    => '退款失败',
//    ];

    static $payTypeMap = [
        self::PAY_STATUS_NO               => '未支付',
        self::PAY_TYPE_WECHAT             => '微信支付',
        self::PAY_TYPE_BALANCE            => '余额支付',
        self::PAY_TYPE_WECHAT_AND_BALANCE => '余额 + 微信',
    ];


    const PAYMENT_TIMEOUT = 1800; // 超时时间

    public function member()
    {
        return $this->belongsTo('member', 'member_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }

    public function shop()
    {
        return $this->belongsTo('shop', 'shop_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }

    public function car()
    {
        return $this->belongsTo('car', 'car_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }

    public function agent()
    {
        return $this->belongsTo('agent', 'agent_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }

    public function coupon()
    {
        return $this->belongsTo('coupon', 'coupon_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }

    public function orderGoods()
    {
        return $this->hasMany('OrderGoods', 'order_id');
    }

    public function comment()
    {
        return $this->hasOne('orderComment', 'order_id');
    }

    public function orderComment()
    {
        return $this->hasOne('orderComment', 'order_id');
    }

    public function aftersalesc()
    {
        return $this->hasOne('OrderAftersales', 'order_id');
    }

//    public function getPayTypeAttr($value)
//    {
//        return self::$payTypeMap[$value];
//    }

    public function getCreateTimeAttr($value)
    {
        return $value;
    }

    public function getExpiresTimeAttr($value)
    {
        return !empty($value) ? date('Y.m.d H:i:s',$value) : '';
    }

    public function getAuditTimeAttr($value)
    {
        return !empty($value) ? date('Y.m.d H:i:s',$value) : '';
    }

    /**
     * 生成订单号
     * @return string
     * @throws \Exception
     */
    public static function generateOrderSn(): ?string
    {
        do {
            $sn = date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
        } while (self::where('order_sn', $sn)->find());

        return $sn;
    }

    /**
     * 生成核销码
     * @return string|null
     */
    public static function generateAuditCode(): ?string
    {
        return uniqid("MC");
    }

    /**
     * 获取订单数据
     * @param $orderId
     * @param $memberId
     * @return array|bool|\PDOStatement|string|Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getOrderById($orderId, $memberId)
    {
        return self::where([
            'id'        => $orderId,
            'member_id' => $memberId,
        ])->find();
    }

    /**
     * 获取会员消费记录
     * @param $memberId
     * @param \Closure|null $closure
     * @return \think\Paginator
     * @throws \think\exception\DbException
     */
    public static function memberOrderPayRecord($memberId, ?\Closure $closure = null)
    {
        return self::where('member_id', $memberId)
            ->whereIn('order_status', [self::ORDER_STATUS_WAIT_COMMENT, self::ORDER_STATUS_OK])
            ->where(function ($query) use ($closure) {
                if ($closure instanceof \Closure) {
                    $closure($query);
                }
            })->order('audit_time desc')->paginate();
    }

    /**
     * 获取商家消费记录
     * @param $shopId
     * @param \Closure|null $closure
     * @return \think\Paginator
     * @throws \think\exception\DbException
     */
    public static function shopOrderPayRecord($shopId, ?\Closure $closure = null)
    {
        return self::where('shop_id', $shopId)
            ->with(['member','car','orderGoods'])
            ->whereIn('order_status', [self::ORDER_STATUS_WAIT_COMMENT, self::ORDER_STATUS_OK])
            ->where(function ($query) use ($closure) {
                if ($closure instanceof \Closure) {
                    $closure($query);
                }
            })->order('audit_time desc')->paginate();
    }

    /**
     * 订单数量
     * @param int $status
     * @return int|string
     * @throws \think\Exception
     */
    public static function orderNum(int $status = -1)
    {
        return self::where('shop_id', MemberVo::instance()->getShopId())->where(function ($query) use ($status){
            if($status >= 0) return $query->where('order_status', $status);
        })->count();
    }


    /**
     * 获取店铺会员列表
     * @param $shopId
     * @param \Closure|null $closure
     * @return \think\Paginator
     * @throws \think\exception\DbException
     */
    public static function shopMember($shopId,$keyword='')
    {
        $where['order.shop_id'] = $shopId;
        $where['order.order_status'] = ['in',[self::ORDER_STATUS_WAIT_COMMENT, self::ORDER_STATUS_OK]];
        if (!empty($keyword)){
            $where['member.member_mobile|member.member_name|car.car_numbers'] = ['like','%'.$keyword.'%'];
        }
        return self::field('id')->where($where)->with(['member','car'])->group('order.member_id')->order('order.audit_time desc')->paginate()->each(function ($item){
            $item['member_avatar'] = $item['member']['member_avatar'];
            $item['member_mobile'] = $item['member']['member_mobile'];
            $item['member_name'] = $item['member']['member_name'];
            $item['member_id'] = $item['member']['id'];
            unset($item['id'],$item['member'],$item['car']);
            return $item;
        });
    }


    /**
     * 获取店铺会员消费列表
     * @param $shopId
     * @param \Closure|null $closure
     * @return \think\Paginator
     * @throws \think\exception\DbException
     */
    public static function shopMemberOrders($shopId,$params)
    {
        $where['order.shop_id'] = $shopId;
        $where['order.member_id'] = $params['member_id'];
        if (isset($params['keyword']) && !empty($params['keyword'])){
            $orders = OrderGoods::where(['member_id'=>$params['member_id'],'shop_id'=>MemberVo::instance()->getShopId(),'goods_name'=>['like','%'.$params['keyword'].'%']])->column('order_id');
            $where['order.id'] = ['in',$orders];
        }
        if (isset($params['car_id']) && !empty($params['car_id'])){
            $where['order.car_id'] = $params['car_id'];
        }
        $where['order.order_status'] = ['in',[self::ORDER_STATUS_WAIT_COMMENT, self::ORDER_STATUS_OK]];
        return self::field('id,order_amount,audit_time')->where($where)->with(['car','orderGoods','shop'])->order('order.createtime desc')->paginate()->each(function (&$item){
            $item['shop_name'] = $item['shop']['shop_name'];
            $item['goods_name'] = '';
            if (isset($item['order_goods'][0]))
                $item['goods_name'] = $item['order_goods'][0]['goods_name'];
            $item['car_numbers'] = $item['car']['car_numbers'];
            unset($item['car'],$item['order_goods'],$item['shop']);
            return $item;
        });
    }

}
